/*
 * This file is subject to the terms of the GFX License. If a copy of
 * the license was not distributed with this file, you can obtain one at:
 *
 *              http://ugfx.org/license.html
 */

/**
 * @file    boards/addons/gdisp/board_SSD1306_spi.h
 * @brief   GDISP Graphic Driver subsystem board interface for the SSD1306 display.
 *
 * @note	This file contains a mix of hardware specific and operating system specific
 *			code. You will need to change it for your CPU and/or operating system.
 */

#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H

// The command byte to put on the front of each page line
#define SSD1306_PAGE_PREFIX		0x40			 		// Co = 0, D/C = 1

// For a multiple display configuration we would put all this in a structure and then
//	set g->board to that structure.

#define SSD1306_MISO_PORT		GPIOB
#define SSD1306_MISO_PIN		GPIO_PIN_14
#define SSD1306_MOSI_PORT		GPIOB
#define SSD1306_MOSI_PIN		GPIO_PIN_15
#define SSD1306_SCK_PORT		GPIOB
#define SSD1306_SCK_PIN			GPIO_PIN_13

#define SSD1306_CS_PORT			GPIOA
#define SSD1306_CS_PIN			GPIO_PIN_3
#define SSD1306_DC_PORT		        GPIOA
#define SSD1306_DC_PIN			GPIO_PIN_4
#define SSD1306_RESET_PORT		GPIOA
#define SSD1306_RESET_PIN		GPIO_PIN_5

#define SET_RST					HAL_GPIO_WritePin(SSD1306_RESET_PORT, SSD1306_RESET_PIN, GPIO_PIN_SET);
#define CLR_RST					HAL_GPIO_WritePin(SSD1306_RESET_PORT, SSD1306_RESET_PIN, GPIO_PIN_RESET);

extern SPI_HandleTypeDef hspi2;

static void init_board(GDisplay *g) {
	// As we are not using multiple displays we set g->board to NULL as we don't use it.
	g->board = 0;
}

static void post_init_board(GDisplay *g) {
	(void) g;
}

static void setpin_reset(GDisplay *g, bool_t state) {
	(void) g;
	if(state)
		CLR_RST
	else
		SET_RST
}

static void acquire_bus(GDisplay *g) {
	(void) g;
}

static void release_bus(GDisplay *g) {
	(void) g;
}

static void write_cmd(GDisplay *g, uint8_t cmd) {
	(void)	g;
        HAL_GPIO_WritePin(SSD1306_CS_PORT, SSD1306_CS_PIN, GPIO_PIN_SET);
        HAL_GPIO_WritePin(SSD1306_DC_PORT, SSD1306_DC_PIN, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(SSD1306_CS_PORT, SSD1306_CS_PIN, GPIO_PIN_RESET);
        
        HAL_SPI_Transmit(&hspi2, &cmd, 1, 10);
        HAL_GPIO_WritePin(SSD1306_CS_PORT, SSD1306_CS_PIN, GPIO_PIN_SET);
}

static void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
	(void) g;
        HAL_GPIO_WritePin(SSD1306_CS_PORT, SSD1306_CS_PIN, GPIO_PIN_SET);
        HAL_GPIO_WritePin(SSD1306_DC_PORT, SSD1306_DC_PIN, GPIO_PIN_SET);
        HAL_GPIO_WritePin(SSD1306_CS_PORT, SSD1306_CS_PIN, GPIO_PIN_RESET);
        osDelay(1);
        HAL_StatusTypeDef status = HAL_SPI_Transmit_DMA(&hspi2, data, length);
        if (status != HAL_OK) {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
          osDelay(200);
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
          
        }
        HAL_GPIO_WritePin(SSD1306_CS_PORT, SSD1306_CS_PIN, GPIO_PIN_SET);

}


#endif /* _GDISP_LLD_BOARD_H */

